package com.summerbird.mallchat.common.chat.service.strategy.msg;

import com.summerbird.mallchat.common.chat.dao.MessageDao;
import com.summerbird.mallchat.common.chat.domain.entity.Message;
import com.summerbird.mallchat.common.chat.domain.entity.msg.MessageExtra;
import com.summerbird.mallchat.common.chat.domain.enums.MessageStatusEnum;
import com.summerbird.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.summerbird.mallchat.common.chat.domain.vo.request.msg.TextMsgReq;
import com.summerbird.mallchat.common.chat.domain.vo.response.msg.TextMsgResp;
import com.summerbird.mallchat.common.chat.service.adapter.MessageAdapter;
import com.summerbird.mallchat.common.chat.service.cache.MsgCache;
import com.summerbird.mallchat.common.common.domain.enums.YesOrNoEnum;
import com.summerbird.mallchat.common.common.utils.AssertUtil;
import com.summerbird.mallchat.common.common.utils.sensitiveWord.SensitiveWordBs;
import com.summerbird.mallchat.common.user.domain.entity.User;
import com.summerbird.mallchat.common.user.domain.enums.RoleEnum;
import com.summerbird.mallchat.common.user.service.IRoleService;
import com.summerbird.mallchat.common.user.service.cache.UserCache;
import com.summerbird.mallchat.common.user.service.cache.UserInfoCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class TextMsgHandler extends AbstractMsgHandler<TextMsgReq> {

    @Autowired
    private MessageDao messageDao;
    @Autowired
    private MsgCache msgCache;
    @Autowired
    private UserCache userCache;
    @Autowired
    private UserInfoCache userInfoCache;
    @Autowired
    private IRoleService iRoleService;
    @Autowired
    private SensitiveWordBs sensitiveWordBs;

    @Override
    MessageTypeEnum getMsgTypeEnum() {
        return MessageTypeEnum.TEXT;
    }

    @Override
    protected void saveMsg(Message message, TextMsgReq body) {
        MessageExtra extra = Optional.ofNullable(message.getExtra()).orElse(new MessageExtra());
        Message update = new Message();
        update.setId(message.getId());
        update.setExtra(extra);
        // 过滤敏感词
        update.setContent(sensitiveWordBs.filter(body.getContent()));
        // 如果有回复消息
        if(Objects.nonNull(body.getReplyMsgId())){
            Integer count = messageDao.getGapCount(message.getRoomId(), body.getReplyMsgId(), message.getId());
            update.setGapCount(count);
            update.setReplyMsgId(body.getReplyMsgId());
        }

        // 艾特功能
        if(!CollectionUtils.isEmpty(body.getAtUidList())){
            extra.setAtUidList(body.getAtUidList());
        }

        messageDao.updateById(update);

    }

    @Override
    protected void checkMsg(TextMsgReq body, Long roomId, Long uid) {
        // 校验回复消息
        if(Objects.nonNull(body.getReplyMsgId())){
            Message message = messageDao.getById(body.getReplyMsgId());
            AssertUtil.isNotEmpty(message, "回复消息不存在");
            AssertUtil.equal(roomId, message.getRoomId(), "只能回复相同会话内的消息");
        }
        // 校验艾特消息
        if(!CollectionUtils.isEmpty(body.getAtUidList())){
            List<Long> atUidList = body.getAtUidList().stream().distinct().collect(Collectors.toList());
            Map<Long, User> userMap = userInfoCache.getBatch(atUidList);
            //如果@用户不存在，userInfoCache 返回的map中依然存在该key，但是value为null，需要过滤掉再校验
            long mapSize = userMap.values().stream().filter(Objects::nonNull).count();
            AssertUtil.equal(mapSize, (long)atUidList.size(), "@用户不存在");
            boolean atAll = body.getAtUidList().contains(0L);
            if(atAll){
                AssertUtil.isTrue(iRoleService.hasPower(uid, RoleEnum.CHAT_MANAGER), "没有权限");
            }
        }
    }

    @Override
    public Object showMsg(Message msg) {
        TextMsgResp resp = new TextMsgResp();
        resp.setContent(msg.getContent());
        resp.setAtUidList(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getAtUidList).orElse(null));
        resp.setUrlContentMap(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getUrlContentMap).orElse(null));
        // 回复消息
        Optional<Message> reply = Optional.ofNullable(msg.getReplyMsgId())
                .map(msgCache::getMsg)
                .filter(a -> Objects.equals(a.getStatus(), MessageStatusEnum.NORMAL.getStatus()));
        if(reply.isPresent()){
            Message replyMessage = reply.get();
            TextMsgResp.ReplyMsg replyMsg = new TextMsgResp.ReplyMsg();
            replyMsg.setId(replyMessage.getId());
            replyMsg.setUid(replyMessage.getFromUid());
            replyMsg.setType(replyMessage.getType());
            User replyUser = userCache.getUserInfo(replyMessage.getFromUid());
            replyMsg.setGapCount(msg.getGapCount());
            // 限制跳转消息的消息间隔数量
            replyMsg.setCanCallback(YesOrNoEnum.toStatus(Objects.nonNull(msg.getGapCount()) && msg.getGapCount() <= MessageAdapter.CAN_CALLBACK_GAP_COUNT));
            replyMsg.setUsername(replyUser.getName());
            replyMsg.setBody(MsgHandlerFactory.getStrategyNoNull(replyMessage.getType()).showReplyMsg(replyMessage));
            resp.setReply(replyMsg);
        }
        return resp;
    }

    @Override
    public Object showReplyMsg(Message msg) {
        return msg.getContent();
    }

    @Override
    public String showContactMsg(Message msg) {
        return msg.getContent();
    }
}
